/**
 * phi
 */

// ----------------------------------------------------------------
// util 
// ----------------------------------------------------------------
var $id = function(id) { return document.getElementById(id); };


// ----------------------------------------------------------------
// param
// ----------------------------------------------------------------
var FPS = 30;
var TEXT = "Time is Money.";
var TEXT_MAX_HEIGHT = 250;
var PARTICLE_SPACE  = 10;
var PARTICLE_SIZE   = 5;

// ----------------------------------------------------------------
// global
// ----------------------------------------------------------------
var global = {
    canvas: null,
    context: null,
    mouse: {
        x: 0,
        y: 0,
        click: false,
        enable: false
    },
    keyboard: [],
    
    root: null,
    bullet: null,
    particles: [],
};

// ----------------------------------------------------------------
// application
// ----------------------------------------------------------------

window.addEventListener("load", function()
{
    init();
    run();
    
    var gui = new GUI();
    
    gui.add(window, "TEXT").onChange(init);
    gui.add(window, "TEXT_MAX_HEIGHT", 100, 500).onChange(init);
    
    gui.add(window, "PARTICLE_SPACE", 5, 20, 1).onChange(init);
    gui.add(window, "PARTICLE_SIZE", 5, 20, 1).onChange(init);
    
    /*
    global.root = new ElementContainer();
    
    global.root.appendChild(new Particle2("a"));
    global.root.appendChild(new Particle2("b"));
    global.root.appendChild(new Particle2("c"));
    global.root.exec("update");
    global.root.exec("update");
    global.root.exec("draw", "aa");
    */
    
}, false);

/**
 * 初期化
 */
var init = function()
{
    var cvs = global.canvas = $id("c");
    var ctx = global.context= global.canvas.getContext("2d");
    
    cvs.onmousedown = function() { global.mouse.click = true; }
    cvs.onmouseup   = function() { global.mouse.click = false; }
    cvs.onmousemove = updateMousePos;
    document.onkeydown  = keyDownFunction;
    document.onkeyup    = keyUpFunction;
    
    cvs.width = window.innerWidth;
    cvs.height= window.innerHeight;
    
    // コンテナ生成
    global.root = new ElementContainer();
    
    // プレイヤー生成
    global.root.appendChild(new Player());
    
    // パーティクルセットアップ
    setupParticle();
};

/**
 * 実行
 */
var run = function()
{
    var loop = function()
    {
        update();
        draw();
        setTimeout(loop, 1000.0/FPS);
    };
    
    setTimeout(loop, 1000.0/FPS);
};


var update = function()
{
    global.root.exec("update");
};


var draw = function()
{
    var cvs = global.canvas;
    var ctx = global.context;
    ctx.fillStyle = "black";
    ctx.fillRect(0, 0, cvs.width, cvs.height);
    
    // プレイヤー描画
    global.root.exec("draw", ctx);
};


var setupParticle = function()
{
    // テクスチャレンダリング用キャンバスを生成
    var tempCanvas = document.createElement("canvas");
    var tempContext= tempCanvas.getContext("2d");
    tempCanvas.width  = global.canvas.width;
    tempCanvas.height = TEXT_MAX_HEIGHT;
    // テキストを描画
    tempContext.font = TEXT_MAX_HEIGHT + "px 'Jockey One'";
    tempContext.textAlign    = "center"
    tempContext.textBaseline = "middle";
    tempContext.fillText(
        TEXT,
        tempCanvas.width/2,
        TEXT_MAX_HEIGHT/2
    );
    
    // パーティクルをセットアップ
    global.particles = global.root.appendChild(new ElementContainer());
    global.particles.update = function()    { this.exec("update"); };
    global.particles.draw   = function(ctx) { this.exec("draw", ctx); };
    
    var imageData = tempContext.getImageData(0, 0, tempCanvas.width, tempCanvas.height);
    // var heightOffset = global.canvas.height/2 - TEXT_MAX_HEIGHT/2;
    var heightOffset = 100;
    
    for (var height=0; height<tempCanvas.height; height+=PARTICLE_SPACE) {
        
        for (var width=0; width<tempCanvas.width; width+=PARTICLE_SPACE) {
            
            pixel = imageData.data[ ((width + (height*tempCanvas.width))*4) - 1 ];
            
            if (pixel == 255) {
                global.particles.appendChild(new Particle(
                    width, height+heightOffset, "hsl(" + Math.floor(Math.random()*360) + ", 100%, 50%)"
                ));
            }
            
        }
        
    }
};


var updateMousePos = function(e)
{
    global.mouse.x = e.offsetX || (e.layerX - this.offsetLeft);
    global.mouse.y = e.offsetY || (e.layerY - this.offsetTop);
    global.mouse.enable = true;
};


var keyDownFunction = function(e)
{
    global.keyboard[e.keyCode] = true;
};

var keyUpFunction = function(e)
{
    global.keyboard[e.keyCode] = false;
};


window.addEventListener("resize", init);

/**
 * Particle class
 */
var Particle = function(x, y, color)
{
    this.x = x || global.canvas.width/2 - 10;
    this.y = y || global.canvas.height - 100;
    this.color  = color || "white";
    this.size   = PARTICLE_SIZE;
};


Particle.prototype =
{
    x: null,
    y: null,
    
    update: function()
    {
        var lensqr = (this.x - global.mouse.x)*(this.x - global.mouse.x) + (this.y - global.mouse.y)*(this.y - global.mouse.y);
        
        if (lensqr < 75*75) {
            this.enable = true;
            
            // パーティクル生成
            if (global.mouse.click) {
                global.root.appendChild(new ClickParticle(this.x, this.y, "hsl(" + Math.floor(Math.random()*360) + ", 100%, 50%)"));
            }
        }
        else {
            this.enable = false;
        }
        
        if (this.destroy) {
            this.parent.removeChild(this);
        }

    },
    
    draw: function(ctx)
    {
        ctx.save();
        ctx.globalCompositeOperation = "lighter";
        ctx.fillStyle = (this.enable) ? this.color : "white";
        
        ctx.beginPath();
        ctx.arc(this.x, this.y, PARTICLE_SIZE, 0, Math.PI*2, false);
        ctx.fill();
        ctx.closePath();
        
        ctx.restore();
    }
};


/**
 * プレイヤー
 */
var Player = function(x, y)
{
    this.x = x || global.canvas.width/2 - 10;
    this.y = y || global.canvas.height - 100;
};


Player.prototype =
{
    x: null,
    y: null,
    
    update: function()
    {
        if (global.keyboard[37]) this.x -=8;
        if (global.keyboard[39]) this.x +=8;
        if (global.keyboard[90] && global.bullet==null) {
            global.bullet = global.root.appendChild( new Bullet(this.x, this.y) );
        }
    },
    
    draw: function(ctx)
    {
        /*
        ctx.fillStyle = "red";
        
        ctx.beginPath();
        ctx.arc(this.x, this.y, 20, 0, Math.PI*2, false);
        ctx.fill();
        ctx.closePath();
        */
        
        ctx.fillStyle = "white";
        ctx.fillRect(this.x-20, this.y-7, 40, 15);
        ctx.fillRect(this.x-18, this.y-9, 36,  2);
        ctx.fillRect(this.x-3, this.y-13, 6, 4);
    }
};



/**
 * 
 */
var Bullet = function(x, y)
{
    this.x = x || 0;
    this.y = y || 0;
    this.size = 5;
};

Bullet.prototype =
{
    x: null,
    y: null,
    
    update: function()
    {
        /**
         * 弾と敵の衝突判定
         */
        for (var j=0; j<5; ++j) {
            this.y -= 10;
            for (var i=0,len=global.particles.children.length; i<len; ++i) {
                var particle = global.particles.children[i];
                
                if (isCollision(this, particle)) {
                    // クラッシュパーティクル生成
                    createCrashParticle(particle.x, particle.y);
                    global.bullet = null;
                    this.parent.removeChild(this);
                    particle.destroy = true;
                }
            }
        }

        
        if (this.y < 0) {
            global.bullet = null;
            this.parent.removeChild(this);
        }
    },
    
    draw: function(ctx)
    {
        ctx.fillStyle = "white";
        ctx.fillRect(this.x-2, this.y-10, 1, 20);
    }
};



/**
 * 
 */
var ClickParticle = function(x, y)
{
    this.x = x;
    this.y = y;
    this.angle = Math.random()*360;
    this.speed = Math.random()*8;
    this.alpha = 1;
    this.color = "hsl(" + Math.floor(Math.random()*360) + ", 100%, 50%)";
    this.destroy = false;
};

ClickParticle.prototype =
{
    x: null,
    y: null,
    
    update: function()
    {
        this.y-=5;
        this.alpha -= 0.025;
        
        if (this.alpha < 0) {
            this.parent.removeChild(this);
        }
    },
    
    draw: function(ctx)
    {
        ctx.save();
        ctx.globalCompositeOperation = "lighter";
    
        ctx.fillStyle = this.color;
        ctx.globalAlpha = this.alpha;
        
        ctx.beginPath();
        ctx.arc(this.x, this.y, PARTICLE_SIZE, 0, Math.PI*2, false);
        ctx.fill();
        ctx.closePath();
        
        ctx.restore();
    }
};

/**
 * 
 */
var CrashParticle = function(x, y)
{
    this.x = x;
    this.y = y;
    this.angle = Math.random()*360;
    this.speed = Math.random()*8;
    this.alpha = 1;
    this.color = "hsl(" + Math.floor(Math.random()*360) + ", 100%, 50%)";
    this.destroy = false;
};

CrashParticle.prototype =
{
    x: null,
    y: null,
    
    update: function()
    {
        this.x += Math.cos(Math.PI*180*this.angle)*(this.speed*this.alpha);
        this.y += Math.sin(Math.PI*180*this.angle)*(this.speed*this.alpha);
        this.alpha -= 0.01
        if (this.alpha <= 0) {
            this.parent.removeChild(this);
        }
    },
    
    draw: function(ctx)
    {
        ctx.save();
        ctx.globalCompositeOperation = "lighter";
    
        ctx.fillStyle = this.color;
        ctx.globalAlpha = this.alpha;
        
        ctx.beginPath();
        ctx.arc(this.x, this.y, PARTICLE_SIZE, 0, Math.PI*2, false);
        ctx.fill();
        ctx.closePath();
        
        ctx.restore();
    }
};


var createCrashParticle = function(x, y)
{
    for (var i=0; i<10; ++i) {
        global.root.appendChild( new CrashParticle(x, y) );
    }
}

var isCollision = function(obj0, obj1)
{
    var lenX = obj0.x - obj1.x;
    var lenY = obj0.y - obj1.y;
    var size = obj0.size + obj1.size;
    return (lenX*lenX)+(lenY*lenY) < (size*size);
};
























